package com.jeeplus.test.jlnu.changeStuInfo.service.impl;


import com.google.common.base.CaseFormat;
import com.jeeplus.sys.domain.Office;
import com.jeeplus.sys.service.OfficeService;

import com.jeeplus.test.jlnu.changeStuInfo.constant.enums.ChangeStuInfoEnum;
import com.jeeplus.test.jlnu.changeStuInfo.domain.entity.ChangeStuInfo;
import com.jeeplus.test.jlnu.changeStuInfo.domain.entity.ChangeStuInfoHistory;
import com.jeeplus.test.jlnu.changeStuInfo.domain.vo.ChangeStuInfoReq;
import com.jeeplus.test.jlnu.changeStuInfo.mapper.ChangeAuditMapper;
import com.jeeplus.test.jlnu.changeStuInfo.mapper.ChangeStuInfoDetailMapper;
import com.jeeplus.test.jlnu.changeStuInfo.mapper.ChangeStuInfoMapper;
import com.jeeplus.test.jlnu.changeStuInfo.service.ChangeStuInfoService;
import com.jeeplus.test.jlnu.graduationInfo.domain.vo.NewGraduationInfoReqVo;
import com.jeeplus.test.jlnu.graduationInfo.mapper.NewGraduationInfoMapper;
import com.jeeplus.test.tools.resp.R;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class ChangeStuInfoServiceImpl implements ChangeStuInfoService {

    @Autowired
    private ChangeStuInfoMapper changeStuInfoMapper;

    @Autowired
    private ChangeAuditMapper changeAuditMapper;

    @Autowired
    private OfficeService officeService;

    @Autowired
    private ChangeStuInfoDetailMapper changeStuInfoDetailMapper;

    @Autowired
    private NewGraduationInfoMapper newGraduationInfoMapper;

    // 允许修改的字段集合
    private static final Set<ChangeStuInfoEnum> ALLOWED_FIELDS =
            Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
                    ChangeStuInfoEnum.COLLEGE_NAME,
                    ChangeStuInfoEnum.DEPARTMENT_NAME,
                    ChangeStuInfoEnum.SERIAL_NUMBER,
                    ChangeStuInfoEnum.MAJOR_CODE,
                    ChangeStuInfoEnum.MAJOR_NAME,
                    ChangeStuInfoEnum.GRADE,
                    ChangeStuInfoEnum.NAME,
                    ChangeStuInfoEnum.CLASS_ID,
                    ChangeStuInfoEnum.KSH,
                    ChangeStuInfoEnum.EXAM_TICKET_NUMBER,
                    ChangeStuInfoEnum.BIRTH_DATE,
                    ChangeStuInfoEnum.GENDER,
                    ChangeStuInfoEnum.ETHNICITY,
                    ChangeStuInfoEnum.ID_CARD_NUMBER,
                    ChangeStuInfoEnum.EDUCATION_LEVEL,
                    ChangeStuInfoEnum.STUDY_FORM,
                    ChangeStuInfoEnum.ACADEMIC_SYSTEM,
                    ChangeStuInfoEnum.ENROLLMENT_DATE,
                    ChangeStuInfoEnum.POLITICAL_STATUS,
                    ChangeStuInfoEnum.STUDENT_SOURCE,
                    ChangeStuInfoEnum.AREA_CODE,
                    ChangeStuInfoEnum.RESPONSIBLE_PERSON,
                    ChangeStuInfoEnum.RECORD_DATE,
                    ChangeStuInfoEnum.SPECIFICATION,
                    ChangeStuInfoEnum.COPIES,
                    ChangeStuInfoEnum.PAGES,
                    ChangeStuInfoEnum.ARCHIVE_UNIT,
                    ChangeStuInfoEnum.TRANSFER_PERSON,
                    ChangeStuInfoEnum.RECEIVER,
                    ChangeStuInfoEnum.TRANSFER_TIME,
                    ChangeStuInfoEnum.ARCHIVE_NUMBER,
                    ChangeStuInfoEnum.CASE_TITLE,
                    ChangeStuInfoEnum.DOCUMENT_TITLE,
                    ChangeStuInfoEnum.PAGE_LOCATION,
                    ChangeStuInfoEnum.SOURCE_REMARK,
                    ChangeStuInfoEnum.STUDENT_ID,
                    ChangeStuInfoEnum.STUDENT_IDS

            )));


    private static final Map<ChangeStuInfoEnum, Field> FIELD_CACHE = new HashMap<>();

    static {
        for (ChangeStuInfoEnum field : ALLOWED_FIELDS) {
            try {
                String javaFieldName = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, field.name());
                Field javaField = ChangeStuInfo.class.getDeclaredField(javaFieldName);
                javaField.setAccessible(true);
                FIELD_CACHE.put(field, javaField);
            } catch (NoSuchFieldException e) {
                //
            }
        }
    }

    //树查询
    @Override
    public List<ChangeStuInfo> selectValueByOfficeId(ChangeStuInfoReq changeStuInfoReq) {
        String officeId = changeStuInfoReq.getOfficeId();
        String officeType = changeStuInfoDetailMapper.getTypeById(officeId);
        if (officeType != null && !"".equals(officeType) && officeType.equals("4")) {
            changeStuInfoReq.setOfficeId("1854766690538450945");
        }
        // 1. 获取分页结果和字段配置信息
        if (org.apache.commons.lang.StringUtils.isNotEmpty(changeStuInfoReq.getOfficeId())) {
            //获取机构下所有层级
            List<String> officesList = officeService.getOfficesTreeByParentId(changeStuInfoReq.getOfficeId());
            officesList.add(changeStuInfoReq.getOfficeId());
            changeStuInfoReq.setOfficesList(officesList);
            changeStuInfoReq.setOfficeId("");

        }

        // 处理type
        if (org.apache.commons.lang.StringUtils.isNotEmpty(changeStuInfoReq.getApproveState())) {
            String[] arr = changeStuInfoReq.getApproveState().split(",");
            List<String> list = Arrays.asList(arr);
            changeStuInfoReq.setApproveStateList(list);
        }


        List<ChangeStuInfo> changeStuInfoPage = changeStuInfoMapper.selectValueByOfficeId(changeStuInfoReq);

        return changeStuInfoPage;
    }

    //批量修改
    @Override
    public int updateChangeStu(List<String> studentIds, ChangeStuInfo changeStuInfo) {

        // 将 ChangeStuInfo 转换为 GraduationInfoReqVo
        NewGraduationInfoReqVo graduationParam = convertChangeStuToGraduationReq(changeStuInfo);

        // 执行批量更新
        newGraduationInfoMapper.batchUpdate(studentIds, graduationParam);
        return changeStuInfoMapper.updateChangeStu(studentIds, changeStuInfo);
    }

    //学籍修改
    @Override
    public R processChangeRequest(ChangeStuInfo changeStuInfo) {
        // 获取数据基础校验
        String studentId = changeStuInfo.getStudentIds().get(0);
        ChangeStuInfo original = changeStuInfoMapper.getByStudentId(studentId);
        if (original == null) return R.error("9999", "学号不存在");
        String officeType;
        Boolean isStudent = false;
        //判断是否是学生端提交的修改
        if(changeStuInfo.getStudentSign() !=null && changeStuInfo.getStudentSign().equals("sign")){
            officeType = original.getOfficeId();
            changeStuInfo.setOfficeId(officeType);
            isStudent = true;
        }else {
            officeType = getOfficeType(changeStuInfo.getOfficeId());
        }
        List<ChangeStuInfo> changeStuInfos = new ArrayList<>();


        // 检查是否存在待审批状态数据
//        if (changeAuditMapper.countByStudentIdAndStates(studentId, Arrays.asList(2, 3)) > 0) {
//            return R.error("9999", "存在待审批记录不可修改");
//        }

        // 过滤无效或未更改的字段
        Map<ChangeStuInfoEnum, String> validData = cleanAndFilterData(changeStuInfo);
        if (validData.isEmpty()) {
            return R.error("9999", "未检测到有效变更");
        }

        // 获取编辑记录
        List<ChangeStuInfoHistory> editableRecords = getEditableRecords(studentId);
        Map<String, ChangeStuInfoHistory> fieldRecordMap = buildFieldRecordMap(editableRecords);

        // 处理变更字段
        List<ChangeStuInfoHistory> audits = processFieldChanges(validData, original, changeStuInfo, fieldRecordMap, officeType);


        // 处理officeType为4
        if ("4".equals(officeType) || "1".equals(officeType)) {
            updateOrInsertAudits(audits, changeStuInfo, original.getId(), officeType);
            handleOfficeType4(changeStuInfo, changeStuInfos);
            return R.suc();
        }else {
            if(isStudent){
                changeStuInfo.setApproveState(2);
            }else {
                changeStuInfo.setApproveState(3);
            }

        }

        // 处理approveState为5
        if (Integer.valueOf(5).equals(changeStuInfo.getApproveState())) {
            changeStuInfo.setApproveState(4);
            changeStuInfo.setApproveRemark("已通过");
            handleApproveState5(changeStuInfo, changeStuInfos);
            updateOrInsertAudits(audits, changeStuInfo, original.getId(), officeType);
            return executeBatchUpdate(changeStuInfos);
        }


        // 更新或插入记录
        updateOrInsertAudits(audits, changeStuInfo, original.getId(), officeType);
        return R.suc("变更申请已完成");
    }

    //审批通过
    @Override
    public void approval(String officeId, List<Long> ids) {
        String officeType = getOfficeType(officeId);
        ChangeStuInfo changeStuInfo = new ChangeStuInfo();
        if (officeType.equals("4")) {
            //学生工作处
            changeStuInfo.setApproveState(4);

            // 获取原始数据
            Map<Long, ChangeStuInfo> originMap = changeStuInfoMapper.selectBatchIds(ids)
                    .stream()
                    .collect(Collectors.toMap(ChangeStuInfo::getId, Function.identity()));

            // 获取最新变更记录（返回 List）
            List<ChangeStuInfoHistory> changesList = changeStuInfoMapper.getLatestChanges(ids);

            // 收集历史记录ID
            List<Long> historyIds = changesList.stream()
                    .map(ChangeStuInfoHistory::getId)
                    .collect(Collectors.toList());

            // 手动按infoId分组
            Map<Long, List<ChangeStuInfoHistory>> changes = changesList.stream()
                    .collect(Collectors.groupingBy(ChangeStuInfoHistory::getInfoId));

            // 构建更新集合
            List<ChangeStuInfo> updateList = new ArrayList<>();

            changes.forEach((infoId, historyList) -> {
                if (historyList == null) return;  // 防止空列表
                ChangeStuInfo origin = originMap.get(infoId);
                if (origin != null) {
                    historyList.forEach(history -> {
                        applyChange(origin, history.getField(), history.getDataChange());
                    });
                    origin.setApproveState(4);
                    origin.setApproveRemark("已通过");
                    updateList.add(origin);
                }
            });

            // 批量更新
            if (!updateList.isEmpty()) {
                List <ChangeStuInfo> changeStuInfos = new ArrayList<>();
                List <String> studentIds = new ArrayList<>();
                for (ChangeStuInfo stuInfo : updateList) {
                    changeStuInfos.add(stuInfo);
                    studentIds.add(stuInfo.getStudentId());
                    changeStuInfoMapper.batchUpdateByHistory(stuInfo);

                    NewGraduationInfoReqVo graduationParam = convertChangeStuToGraduationReq(stuInfo);
                    newGraduationInfoMapper.batchUpdate(studentIds,graduationParam);

                }
//                changeStuInfoMapper.batchUpdateByHistory(updateList);
            }
            if (!historyIds.isEmpty()) {
                changeAuditMapper.batchUpdateHistoryStatus(4, historyIds);
            }

        } else {
            //学院
            changeStuInfo.setApproveState(3);
        }
        changeStuInfoMapper.batchUpdateApproveState(changeStuInfo, ids);
    }

    //审批驳回
    @Override
    public int approveRefuse(String officeId, List<ChangeStuInfo> changeStuInfos) {
        //  int type = getOfficeType(officeId).equals("4")  ? 2 : 1;
        changeStuInfos.forEach(item -> item.setApproveState(5));
        return changeStuInfoMapper.updateRefuse(changeStuInfos);
    }









    private String getOfficeType(String officeId){

        Office current = getOfficeWithCache(officeId, new HashMap<>());
        // 直接根据当前机构的 type 属性判断类型
        String type = current.getType();
        System.out.println("当前机构" + type);
        return type;
    }

    private Office getOfficeWithCache(String officeId, Map<String, Office> cache) {
        return cache.computeIfAbsent(officeId, k -> officeService.getById(k));
    }

    private Map<ChangeStuInfoEnum, String> cleanAndFilterData(ChangeStuInfo data) {
        Map<ChangeStuInfoEnum, String> validData = new HashMap<>();
        for (ChangeStuInfoEnum field : ALLOWED_FIELDS) {
            if (field == ChangeStuInfoEnum.STUDENT_IDS ||
                    field == ChangeStuInfoEnum.APPROVE_STATES ||
                    field == ChangeStuInfoEnum.ID) {
                continue;
            }

            String value = getFieldValue(data, field);
            if (value != null && !value.isEmpty()) {
                validData.put(field, value);
            }
        }
        return validData;
    }

    private boolean hasMeaningfulChange(String oldVal, String newVal) {
        // 处理双方均为空的情况
        if (oldVal == null && newVal == null) {
            return false;
        }

        // 处理一方为空的情况
        if (oldVal == null || newVal == null) {
            return true; // 例如：旧值为null，新值为""
        }

        // 处理非空字符串比较
        return !oldVal.trim().equals(newVal.trim());
    }

    private String getFieldValue(ChangeStuInfo obj, ChangeStuInfoEnum field) {
        try {
            Field javaField = FIELD_CACHE.get(field);
            if (javaField == null) return null;

            Object value = javaField.get(obj);
            return convertToString(value);
        } catch (Exception e) {
            return null;
        }
    }

    private String convertToString(Object value) {
        if (value == null) return null;
        if (value instanceof Date) {
            return new SimpleDateFormat("yyyy-MM-dd").format((Date) value); // 统一日期格式
        }
        if (value instanceof Number || value instanceof Boolean) {
            return value.toString(); // 数字和布尔类型直接转字符串
        }
        return value.toString().trim(); // 字符串去空格
    }

    private ChangeStuInfoHistory createAuditRecord(ChangeStuInfoEnum field, String oldVal,
                                                   String newVal, Long infoId, ChangeStuInfo data, String officeType) {

        int type = officeType.equals("4") ? 4 : 1;
        return new ChangeStuInfoHistory()
                .setInfoId(infoId)
                .setStudentId(data.getStudentIds().get(0))
                .setField(field.getFieldName())
                .setApproveState(type)
                .setFieldName(field.getComment())
                .setDataHistory(oldVal)
                .setDataChange(newVal)
                .setChangeDate(new Date())
                .setOfficeId(data.getOfficeId());
    }


    private void applyChange(ChangeStuInfo target, String fieldName, String newValue) {
        try {
            Field field = ChangeStuInfo.class.getDeclaredField(convertToCamelCase(fieldName));
            field.setAccessible(true);

            // 处理不同类型转换（示例处理String）
            field.set(target, newValue);
        } catch (Exception e) {
//          System.out.println("字段更新失败 {}: {}", fieldName, newValue, e);
        }
    }

    private String convertToCamelCase(String columnName) {
        if (columnName == null || columnName.isEmpty()) return columnName;

        String[] parts = columnName.split("_");
        StringBuilder camelCase = new StringBuilder(parts[0].toLowerCase());
        for (int i = 1; i < parts.length; i++) {
            camelCase.append(Character.toUpperCase(parts[i].charAt(0)));
            camelCase.append(parts[i].substring(1).toLowerCase());
        }
        return camelCase.toString();
    }




    private void handleOfficeType4(ChangeStuInfo changeStuInfo, List<ChangeStuInfo> changeStuInfos) {
        changeStuInfo.setApproveState(4);
        changeStuInfo.setApproveRemark("已通过");
        changeStuInfos.add(changeStuInfo);


        for (ChangeStuInfo stuInfo : changeStuInfos) {
            changeStuInfoMapper.batchUpdateByHistory(stuInfo);

            NewGraduationInfoReqVo graduationInfoReqVos = (convertChangeStuToGraduationReq(stuInfo));
            newGraduationInfoMapper.batchUpdate(Arrays.asList(stuInfo.getStudentIds().get(0)),graduationInfoReqVos);

        }

//        changeStuInfoMapper.batchUpdateByHistory(changeStuInfos);
    }

    private void handleApproveState5(ChangeStuInfo changeStuInfo, List<ChangeStuInfo> changeStuInfos) {
        changeStuInfo.setApproveState(3);
        changeStuInfos.add(changeStuInfo);
    }

    private R executeBatchUpdate(List<ChangeStuInfo> changeStuInfos) {
        if (!changeStuInfos.isEmpty()) {
            changeStuInfoMapper.batchUpdateState(changeStuInfos);
        }
        return R.suc();
    }

    private List<ChangeStuInfoHistory> getEditableRecords(String studentId) {
        return changeAuditMapper.selectByStudentIdAndStates(studentId, Arrays.asList(1, 4));
    }

    private Map<String, ChangeStuInfoHistory> buildFieldRecordMap(List<ChangeStuInfoHistory> editableRecords) {
        return editableRecords.stream()
                .collect(Collectors.toMap(
                        ChangeStuInfoHistory::getField,
                        r -> r,
                        (existing, replacement) -> existing.getChangeDate().after(replacement.getChangeDate()) ? existing : replacement
                ));
    }

    private List<ChangeStuInfoHistory> processFieldChanges(
            Map<ChangeStuInfoEnum, String> validData,
            ChangeStuInfo original,
            ChangeStuInfo changeStuInfo,
            Map<String, ChangeStuInfoHistory> fieldRecordMap,
            String officeType
    ) {
        List<ChangeStuInfoHistory> audits = new ArrayList<>();
        final Integer currentState = changeStuInfo.getApproveState(); // 获取当前审批状态

        validData.forEach((field, newVal) -> {
            String oldVal = getFieldValue(original, field);
            if (!hasMeaningfulChange(oldVal, newVal)) return;

            String fieldName = field.getFieldName();

            // 新增状态判断逻辑
            if (Integer.valueOf(4).equals(currentState)) {
                // 状态4强制新增记录
                audits.add(createAuditRecord(field, oldVal, newVal, original.getId(), changeStuInfo, officeType));
            } else {
                ChangeStuInfoHistory changeStuInfoHistory = new ChangeStuInfoHistory();
                changeStuInfoHistory.setInfoId(original.getId());
                changeStuInfoHistory.setApproveState(1);
                int count = changeAuditMapper.countByIdAndState(changeStuInfoHistory);
                // 原有逻辑
                if (fieldRecordMap.containsKey(fieldName) && count > 0) {
                    updateExistingRecord(fieldRecordMap.get(fieldName), newVal);
                } else {
                    audits.add(createAuditRecord(field, oldVal, newVal, original.getId(), changeStuInfo, officeType));
                }
            }
        });
        return audits;
    }

    private void updateExistingRecord(ChangeStuInfoHistory record, String newVal) {
        record.setDataChange(newVal)
                .setApproveState(1)
                .setChangeDate(new Date());
        changeAuditMapper.updateByStudentId(record);
    }

    private boolean updateOrInsertAudits(
            List<ChangeStuInfoHistory> audits,
            ChangeStuInfo changeStuInfo,
            Long originalId,
            String officeType
    ) {
        List<Long> ids = Collections.singletonList(originalId);
        changeStuInfoMapper.batchUpdateApproveState(changeStuInfo, ids);
        if (!audits.isEmpty()) {
            changeAuditMapper.insert(audits);
            int targetState = "1".equals(officeType) ? 1 :
                    ("4".equals(officeType) ? 4 : 3);
            changeStuInfo.setApproveState(targetState);
        }

        return true;
    }

    // 转换方法：将 ChangeStuInfo 的字段复制到 GraduationInfoReqVo
    private NewGraduationInfoReqVo convertChangeStuToGraduationReq(ChangeStuInfo changeStuInfo) {
        NewGraduationInfoReqVo vo = new NewGraduationInfoReqVo();
        BeanUtils.copyProperties(changeStuInfo, vo); // 确保字段名一致

        vo.setExamineeNum(changeStuInfo.getKsh());
        vo.setAdmissionNum(changeStuInfo.getExamTicketNumber());
        vo.setNation(changeStuInfo.getEthnicity());
        vo.setIdCard(changeStuInfo.getIdCardNumber());
        vo.setGradation(changeStuInfo.getEducationLevel());
        vo.setPoliticalOutlook(changeStuInfo.getPoliticalStatus());
        vo.setLearningForms(changeStuInfo.getStudyForm());
        vo.setEducationalSystem(changeStuInfo.getAcademicSystem());
        vo.setEnrollmentDate(changeStuInfo.getEnrollmentDate());
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        vo.setTransferor(changeStuInfo.getTransferPerson());
        vo.setPageCount(changeStuInfo.getPages());
        vo.setQuantity(changeStuInfo.getCopies());
        vo.setStandards(changeStuInfo.getSpecification());
        vo.setDateTime(changeStuInfo.getRecordDate());
        try {
            Date date = formatter.parse(changeStuInfo.getBirthDate());
            vo.setBirthday(date);
        } catch (ParseException e) {
            System.out.println("日期格式不匹配！错误信息: " + e.getMessage());
        }
        return vo;
    }

}
